home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / DEMOS / IDEAS / IDEAS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  25.4 KB  |  1,057 lines

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1995. */
  3.  
  4. /*
  5.  * (c) Copyright 1993, Silicon Graphics, Inc.
  6.  * ALL RIGHTS RESERVED 
  7.  * Permission to use, copy, modify, and distribute this software for 
  8.  * any purpose and without fee is hereby granted, provided that the above
  9.  * copyright notice appear in all copies and that both the copyright notice
  10.  * and this permission notice appear in supporting documentation, and that 
  11.  * the name of Silicon Graphics, Inc. not be used in advertising
  12.  * or publicity pertaining to distribution of the software without specific,
  13.  * written prior permission. 
  14.  *
  15.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  16.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  17.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  18.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  19.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  20.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  21.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  22.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  23.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  24.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  25.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  26.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  27.  * 
  28.  * US Government Users Restricted Rights 
  29.  * Use, duplication, or disclosure by the Government is subject to
  30.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  31.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  32.  * clause at DFARS 252.227-7013 and/or in similar or successor
  33.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  34.  * Unpublished-- rights reserved under the copyright laws of the
  35.  * United States.  Contractor/manufacturer is Silicon Graphics,
  36.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  37.  *
  38.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  39.  */
  40. #include <math.h>
  41. #ifdef _WIN32
  42. #include <windows.h>
  43. #include <winsock.h>
  44. #include <sys/timeb.h>
  45. #define gettimeofday(_x, _y)          \
  46. {                                     \
  47.   struct timeb _t;                    \
  48.   ftime(&_t);                         \
  49.   (_x)->tv_sec = _t.time;             \
  50.   (_x)->tv_usec = _t.millitm * 1000;  \
  51. }
  52. #else
  53. #include <sys/time.h>
  54. #endif
  55. /* Some <math.h> files do not define M_PI... */
  56. #ifndef M_PI
  57. #define M_PI 3.14159265358979323846
  58. #endif
  59. #include <stdio.h>
  60. #include <stdlib.h>
  61. #include "objects.h"
  62. #include <GL/glut.h>
  63.  
  64. #define X 0
  65. #define Y 1
  66. #define Z 2
  67.  
  68. #ifndef TRUE
  69. #define TRUE 1
  70. #endif
  71. #ifndef FALSE
  72. #define FALSE 0
  73. #endif
  74.  
  75. #define DEG *M_PI/180.0
  76. #define RAD *180.0/M_PI
  77.  
  78. float move_speed;        /* Spline distance per second */
  79.  
  80. int multisample = 0;        /* Antialias polygons? */
  81. int doublebuffer = 1;        /* Doublebuffer? */
  82.  
  83.  
  84. #define SPEED_SLOW        0.2    /* Spline distances per second */
  85. #define SPEED_MEDIUM        0.4
  86. #define SPEED_FAST        0.7
  87. #define SPEED_SUPER_FAST    1.0
  88.  
  89. #define O_NOMS        7
  90. #define O_4MS        8
  91. #define O_8MS        9
  92. #define O_16MS        10
  93.  
  94. static int RGBA_SB_attributes = GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH | GLUT_MULTISAMPLE;
  95.  
  96. static int RGBA_DB_attributes = GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_MULTISAMPLE;
  97.  
  98. float light1_ambient[] = { 0.0,0.0,0.0,1.0 };
  99. float light1_lcolor[] = { 1.0,1.0,1.0,1.0 };
  100. float light1_position[] = { 0.0,1.0,0.0,0.0 };
  101.  
  102. float light2_ambient[] = { 0.0,0.0,0.0,1.0 };
  103. float light2_lcolor[] = { 0.3,0.3,0.5,1.0 };
  104. float light2_position[] = { -1.0,0.0,0.0,0.0 };
  105.  
  106. float light3_ambient[] = { 0.2,0.2,0.2,1.0 };
  107. float light3_lcolor[] = { 0.2,0.2,0.2,1.0 };
  108. float light3_position[] = { 0.0,-1.0,0.0,0.0 };
  109.  
  110. float lmodel_LVW[] = { 0.0 };
  111. float lmodel_ambient[] = { 0.3,0.3,0.3,1.0 };
  112. float lmodel_TWO[] = { GL_TRUE };
  113.  
  114. float mat_logo_ambient[] = {0.1, 0.1, 0.1, 1.0};
  115. float mat_logo_diffuse[] = {0.5, 0.4, 0.7, 1.0};
  116. float mat_logo_specular[] = {1.0, 1.0, 1.0, 1.0};
  117. float mat_logo_shininess[] = {30.0};
  118.  
  119. float mat_holder_base_ambient[] = {0.0, 0.0, 0.0, 1.0};
  120. float mat_holder_base_diffuse[] = {0.6, 0.6, 0.6, 1.0};
  121. float mat_holder_base_specular[] = {0.8, 0.8, 0.8, 1.0};
  122. float mat_holder_base_shininess[] = {30.0};
  123.  
  124. float mat_holder_rings_ambient[] = { 0.0,0.0,0.0,1.0 };
  125. float mat_holder_rings_diffuse[] = { 0.9,0.8,0.0,1.0 };
  126. float mat_holder_rings_specular[] = { 1.0,1.0,1.0,1.0 };
  127. float mat_holder_rings_shininess[] = { 30.0 };
  128.  
  129. float mat_hemisphere_ambient[] = {0.0, 0.0, 0.0,1.0 };
  130. float mat_hemisphere_diffuse[] = {1.0, 0.2, 0.2,1.0 };
  131. float mat_hemisphere_specular[] = {0.5, 0.5, 0.5,1.0 };
  132. float mat_hemisphere_shininess[] = {20.0};
  133.  
  134. GLubyte stipple[32*32];
  135.  
  136. typedef float vector[3];
  137. typedef float vector4[4];
  138. typedef vector parameter[4];
  139.  
  140. /*
  141.  * Function definitions
  142.  */
  143. static void initialize(void);
  144. static void resize_window(int w, int h);
  145. static void build_table(void);
  146. static parameter *calc_spline_params(vector *ctl_pts, int n);
  147. static void calc_spline(vector v, parameter *params, float current_time);
  148. static void normalize(vector v);
  149. static float dot(vector v1, vector v2);
  150. void draw_table(void);
  151. void draw_logo_shadow(void);
  152. void draw_hemisphere(void);
  153. void draw_logo(void);
  154. void draw_under_table(void);
  155. void draw_i(void);
  156. void draw_d(void);
  157. void draw_e(void);
  158. void draw_a(void);
  159. void draw_s(void);
  160. void draw_n(void);
  161. void draw_m(void);
  162. void draw_o(void);
  163. void draw_t(void);
  164.  
  165. int post_idle = 0;
  166. static void idle(void);
  167. static void do_post_idle(void);
  168. static void display(void);
  169. static void mouse(int b, int s, int x, int y);
  170. static void keyboard(unsigned char c, int x, int y);
  171. static void vis(int);
  172.  
  173. static void init_materials(void) {
  174.   int x, y;
  175.  
  176.   /* Stipple pattern */
  177.   for (y = 0; y < 32; y++)
  178.     for (x = 0; x < 4; x++) 
  179.       stipple[y * 4 + x] = (y % 2) ? 0xaa : 0x55;
  180.  
  181.     glNewList(MAT_LOGO, GL_COMPILE); 
  182.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat_logo_ambient); 
  183.     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_logo_diffuse);
  184.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_logo_specular);
  185.     glMaterialfv(GL_FRONT, GL_SHININESS, mat_logo_shininess);
  186.     glEndList(); 
  187.  
  188.     glNewList( MAT_HOLDER_BASE, GL_COMPILE);
  189.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat_holder_base_ambient); 
  190.     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_holder_base_diffuse);
  191.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_holder_base_specular);
  192.     glMaterialfv(GL_FRONT, GL_SHININESS, mat_holder_base_shininess);
  193.     glEndList();
  194.  
  195.     glNewList(MAT_HOLDER_RINGS, GL_COMPILE); 
  196.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat_holder_rings_ambient); 
  197.     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_holder_rings_diffuse);
  198.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_holder_rings_specular);
  199.     glMaterialfv(GL_FRONT, GL_SHININESS, mat_holder_rings_shininess);
  200.     glEndList();
  201.  
  202.     glNewList(MAT_HEMISPHERE, GL_COMPILE); 
  203.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat_hemisphere_ambient); 
  204.     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_hemisphere_diffuse);
  205.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_hemisphere_specular);
  206.     glMaterialfv(GL_FRONT, GL_SHININESS, mat_hemisphere_shininess);
  207.     glEndList();
  208.  
  209. }
  210.  
  211. void init_lights(void) {
  212.   static float ambient[] = { 0.1, 0.1, 0.1, 1.0 };
  213.   static float diffuse[] = { 0.5, 1.0, 1.0, 1.0 };
  214.   static float position[] = { 90.0, 90.0, 150.0, 0.0 };
  215.   
  216.   glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
  217.   glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
  218.   glLightfv(GL_LIGHT0, GL_POSITION, position);
  219.  
  220.   glLightfv (GL_LIGHT1, GL_AMBIENT, light1_ambient);
  221.   glLightfv (GL_LIGHT1, GL_SPECULAR, light1_lcolor);
  222.   glLightfv (GL_LIGHT1, GL_DIFFUSE, light1_lcolor);
  223.   glLightfv (GL_LIGHT1, GL_POSITION, light1_position);
  224.     
  225.   glLightfv (GL_LIGHT2, GL_AMBIENT, light2_ambient);
  226.   glLightfv (GL_LIGHT2, GL_SPECULAR, light2_lcolor);
  227.   glLightfv (GL_LIGHT2, GL_DIFFUSE, light2_lcolor);
  228.   glLightfv (GL_LIGHT2, GL_POSITION, light2_position);
  229.  
  230.   glLightfv (GL_LIGHT3, GL_AMBIENT, light3_ambient);
  231.   glLightfv (GL_LIGHT3, GL_SPECULAR, light3_lcolor);
  232.   glLightfv (GL_LIGHT3, GL_DIFFUSE, light3_lcolor);
  233.   glLightfv (GL_LIGHT3, GL_POSITION, light3_position);
  234.   
  235.   glLightModelfv (GL_LIGHT_MODEL_LOCAL_VIEWER, lmodel_LVW);
  236.   glLightModelfv (GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
  237. }
  238.  
  239. short dev, val;
  240.  
  241. float current_time=0.0;
  242. float hold_time=0.0;        /* Used when auto-running */
  243.  
  244. float tmplight[] = {
  245.     GL_POSITION, 0.0, 0.0, 0.0, 0.0, 
  246. };
  247.  
  248. GLfloat tv[4][4] = {
  249.   {1.0, 0.0, 0.0, 0.0},
  250.   {0.0, 1.0, 0.0, -1.0},
  251.   {0.0, 0.0, 1.0, 0.0},
  252.   {0.0, 0.0, 0.0, 0.0},
  253. };
  254.  
  255. #define TABLERES 12
  256.  
  257. float pcr, pcg, pcb, pca;
  258.  
  259. vector table_points[TABLERES+1][TABLERES+1];
  260. GLubyte tablecolors[TABLERES+1][TABLERES+1];
  261.  
  262. vector paper_points[4] = {
  263.     {-0.8, 0.0, 0.4},
  264.     {-0.2, 0.0, -1.4},
  265.     {1.0, 0.0, -1.0},
  266.     {0.4, 0.0, 0.8},
  267. };
  268.  
  269. float dot(vector, vector);
  270.  
  271. #define TIME 15
  272. #define START_TIME 0.6
  273.  
  274. vector light_pos_ctl[] = {
  275.  
  276.     {0.0, 1.8, 0.0},
  277.     {0.0, 1.8, 0.0},
  278.     {0.0, 1.6, 0.0},
  279.  
  280.     {0.0, 1.6, 0.0},
  281.     {0.0, 1.6, 0.0},
  282.     {0.0, 1.6, 0.0},
  283.     {0.0, 1.4, 0.0},
  284.  
  285.     {0.0, 1.3, 0.0},
  286.     {-0.2, 1.5, 2.0},
  287.     {0.8, 1.5, -0.4},
  288.     {-0.8, 1.5, -0.4},
  289.  
  290.     {0.8, 2.0, 1.0},
  291.     {1.8, 5.0, -1.8},
  292.     {8.0, 10.0, -4.0},
  293.     {8.0, 10.0, -4.0},
  294.     {8.0, 10.0, -4.0},
  295. };
  296.  
  297. vector logo_pos_ctl[] = {
  298.  
  299.     {0.0, -0.5, 0.0},
  300.  
  301.     {0.0, -0.5, 0.0},
  302.     {0.0, -0.5, 0.0},
  303.  
  304.     {0.0, -0.5, 0.0},
  305.     {0.0, -0.5, 0.0},
  306.     {0.0, -0.5, 0.0},
  307.     {0.0, 0.0, 0.0},
  308.  
  309.     {0.0, 0.6, 0.0},
  310.     {0.0, 0.75, 0.0},
  311.     {0.0, 0.8, 0.0},
  312.     {0.0, 0.8, 0.0},
  313.  
  314.     {0.0, 0.5, 0.0},
  315.     {0.0, 0.5, 0.0},
  316.     {0.0, 0.5, 0.0},
  317.     {0.0, 0.5, 0.0},
  318.     {0.0, 0.5, 0.0},
  319. };
  320.  
  321.  
  322. vector logo_rot_ctl[] = {
  323.  
  324.     {0.0, 0.0, -18.4},
  325.  
  326.     {0.0, 0.0, -18.4},
  327.     {0.0, 0.0, -18.4},
  328.  
  329.     {0.0, 0.0, -18.4},
  330.     {0.0, 0.0, -18.4},
  331.     {0.0, 0.0, -18.4},
  332.     {0.0, 0.0, -18.4},
  333.     {0.0, 0.0, -18.4},
  334.  
  335. /*    {90.0, 0.0, -90.0},
  336.     {180.0, 180.0, 90.0}, */
  337.     {240.0, 360.0, 180.0},
  338.     {90.0, 180.0, 90.0},
  339.  
  340.     {11.9, 0.0, -18.4},
  341.     {11.9, 0.0, -18.4},
  342.     {11.9, 0.0, -18.4},
  343.     {11.9, 0.0, -18.4},
  344.     {11.9, 0.0, -18.4},
  345. };
  346.  
  347.  
  348. vector view_from_ctl[] = {
  349.  
  350.     {-1.0, 1.0, -4.0},
  351.  
  352.     {-1.0, -3.0, -4.0},    /* 0 */
  353.     {-3.0, 1.0, -3.0},    /* 1 */
  354.  
  355.     {-1.8, 2.0, 5.4},    /* 2 */
  356.     {-0.4, 2.0, 1.2},    /* 3 */
  357.     {-0.2, 1.5, 0.6},    /* 4 */
  358.     {-0.2, 1.2, 0.6},    /* 5 */
  359.  
  360.     {-0.8, 1.0, 2.4},    /* 6 */
  361.     {-1.0, 2.0, 3.0},    /* 7 */
  362.     {0.0, 4.0, 3.6},    /* 8 */
  363.     {-0.8, 4.0, 1.2},    /* 9 */
  364.  
  365.     {-0.2, 3.0, 0.6},    /* 10 */
  366.     {-0.1, 2.0, 0.3},    /* 11 */
  367.     {-0.1, 2.0, 0.3},    /* 12 */
  368.     {-0.1, 2.0, 0.3},    /* 13 */
  369.     {-0.1, 2.0, 0.3},    /* 13 */
  370.  
  371.  
  372. };
  373.  
  374. vector view_to_ctl[] = {
  375.  
  376.     {-1.0, 1.0, 0.0},
  377.  
  378.     {-1.0, -3.0, 0.0},
  379.     {-1.0, 1.0, 0.0},
  380.  
  381.     {0.1, 0.0, -0.3},
  382.     {0.1, 0.0, -0.3},
  383.     {0.1, 0.0, -0.3},
  384.     {0.0, 0.2, 0.0},
  385.  
  386.     {0.0, 0.6, 0.0},
  387.     {0.0, 0.8, 0.0},
  388.     {0.0, 0.8, 0.0},
  389.     {0.0, 0.8, 0.0},
  390.  
  391.     {0.0, 0.8, 0.0},
  392.     {0.0, 0.8, 0.0},
  393.     {0.0, 0.8, 0.0},
  394.     {0.0, 0.8, 0.0},
  395.     {0.0, 0.8, 0.0},
  396.  
  397. };
  398.  
  399.  
  400. vector view_from, view_to, logo_pos, logo_rot;
  401. vector4 light_pos;
  402.  
  403. parameter *view_from_spline, *view_to_spline,
  404.       *light_pos_spline, *logo_pos_spline,
  405.       *logo_rot_spline;
  406.  
  407. double a3, a4;
  408.  
  409. void ideas_usage(void)
  410. {
  411.   fprintf(stderr, "Usage: ideas [-a] [-m] [-d] -s{1-4}\n");
  412.   fprintf(stderr, "Press ESC to quit, 1-4 to control speed, any other key\n");
  413.   fprintf(stderr, "to pause.\n");
  414. }
  415.  
  416.   int auto_run;        /* If set, then automatically run forever */
  417.   float new_speed;    /* Set new animation speed? */
  418.   int timejerk;        /* Set to indicate time jerked! (menu pulled down) */
  419.   int paused = 0;    /* Paused? */
  420.   int right = 0;    /* Draw right eye? */
  421.   int resetclock;    /* Reset the clock? */
  422.   float timeoffset;    /* Used to compute timing */
  423.   struct timeval start;
  424.  
  425. int main(int argc, char **argv)
  426. {
  427.   int i;
  428.  
  429.   glutInit(&argc, argv);
  430.  
  431.   auto_run = 0;    /* Don't automatically run forever */
  432.   /* .4 spline distance per second by default */
  433.   move_speed = SPEED_MEDIUM;
  434.   new_speed = SPEED_MEDIUM;
  435.   timeoffset = START_TIME;
  436.   
  437.   for (i = 1; i < argc; i++) {
  438.     if (argv[i][0] != '-') {
  439.       break;
  440.     }
  441.     
  442.     switch(argv[i][1]) {
  443.     case 'a':    /* Keep running forever */
  444.       auto_run = 1;
  445.       break;
  446.     case 'm':    /* Multisample */
  447.       multisample = 1;
  448.       break;
  449.     case 'd':    /* Single buffer */
  450.       doublebuffer = 0;
  451.       break;
  452.     case 's':
  453.       switch(argv[i][2]) {
  454.       case '1':
  455.     move_speed = new_speed = SPEED_SLOW;
  456.     break;
  457.       case '2':
  458.     move_speed = new_speed = SPEED_MEDIUM;
  459.     break;
  460.       case '3':
  461.     move_speed = new_speed = SPEED_FAST;
  462.     break;
  463.       case '4':
  464.     move_speed = new_speed = SPEED_SUPER_FAST;
  465.     break;
  466.       }
  467.       break;
  468.     default:
  469.       ideas_usage();
  470.       break;
  471.     }
  472.   }
  473.   
  474.   initialize();
  475.   
  476.   current_time = timeoffset;
  477.   resetclock = 1;
  478.   timejerk = 0;
  479.   glutMainLoop();
  480.   return 0;             /* ANSI C requires main to return int. */
  481. }
  482.  
  483. static void idle(void) 
  484. {
  485.     if ((current_time) > (TIME*1.0)-3.0) {
  486.       if (auto_run) {
  487.     hold_time += current_time - (TIME - 3.001);
  488.     if (hold_time > 3.0) {    /* 3 second hold */
  489.       hold_time = 0.0;
  490.       resetclock = 1;
  491.     }
  492.       } else {
  493.         if(!resetclock) glutIdleFunc(NULL);
  494.       }
  495.       current_time = (TIME*1.0)-3.001;
  496.     } else {
  497.        post_idle = 1;
  498.     }
  499.     glutPostRedisplay();
  500. }
  501.  
  502. /* ARGSUSED2 */
  503. static void
  504. mouse(int b, int s, int x, int y)
  505. {
  506.    if(b == GLUT_LEFT_BUTTON && s == GLUT_DOWN) {
  507.       resetclock = 1;
  508.       paused = 0;
  509.       glutIdleFunc(idle);
  510.    }
  511. }
  512.  
  513. /* ARGSUSED1 */
  514. static void
  515. keyboard(unsigned char c, int x, int y)
  516. {
  517.    switch(c) {
  518.    case 27:
  519.       exit(0);
  520.       break;
  521.    case '1':
  522.       new_speed = SPEED_SLOW;
  523.       break;
  524.    case '2':
  525.       new_speed = SPEED_MEDIUM;
  526.       break;
  527.    case '3':
  528.       new_speed = SPEED_FAST;
  529.       break;
  530.    case '4':
  531.       new_speed = SPEED_SUPER_FAST;
  532.       break;
  533.    default:
  534.       if (paused) timejerk = 1;
  535.       paused = ~paused;
  536.       if(paused) {
  537.      glutIdleFunc(NULL);
  538.       } else {
  539.      glutIdleFunc(idle);
  540.       }
  541.    }
  542. }
  543.  
  544. static void
  545. vis(int visible)
  546. {
  547.   if (visible == GLUT_VISIBLE) {
  548.       if(!paused) glutIdleFunc(idle);
  549.       do_post_idle();
  550.   } else {
  551.       if(!paused) glutIdleFunc(NULL);
  552.   }
  553. }
  554.  
  555. static void display(void)
  556. {
  557.   float x, y, z, c;
  558.  
  559.     calc_spline(view_from, view_from_spline, current_time);
  560.     calc_spline(view_to, view_to_spline, current_time);
  561.     calc_spline(light_pos, light_pos_spline, current_time);
  562.     light_pos[3] = 0.0;
  563.     calc_spline(logo_pos, logo_pos_spline, current_time);
  564.     calc_spline(logo_rot, logo_rot_spline, current_time);
  565.     
  566.     tmplight[1] = light_pos[X] - logo_pos[X];
  567.     tmplight[2] = light_pos[Y] - logo_pos[Y];
  568.     tmplight[3] = light_pos[Z] - logo_pos[Z];
  569.     
  570.     glNewList(LIGHT_TMP, GL_COMPILE); 
  571.     glMaterialf(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, * tmplight); 
  572.     glEndList();
  573.     
  574.     tv[0][0] = tv[1][1] = tv[2][2] = light_pos[Y];
  575.     
  576.     glColor3ub(0,  0,  0);
  577.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
  578.     
  579.     /*
  580.      * SHADOW
  581.      */
  582.     glMatrixMode(GL_MODELVIEW);
  583.     glLoadIdentity();
  584.     gluLookAt(view_from[X], view_from[Y], view_from[Z], 
  585.           view_to[X], view_to[Y], view_to[Z],
  586.           0.0, 1.0, 0.0);
  587.     
  588.     if (view_from[Y] > 0.0) draw_table();
  589.  
  590.     glEnable(GL_CULL_FACE); 
  591.     glDisable(GL_DEPTH_TEST); 
  592.  
  593.     if (logo_pos[Y] < 0.0) {
  594.       
  595.       if (logo_pos[Y]>-0.33) {
  596.     /* We're emerging from the table */
  597.     c = 1.0 - (logo_pos[Y]) / -0.33;
  598.     pca /= 4.0;
  599.     glColor3ub((GLubyte)(128.0*(1.0-c)*0.5 + 255.0*pca*c),
  600.            (GLubyte)(102.0*(1.0-c)*0.5 + 255.0*pca*c),
  601.            (GLubyte)(179.0*(1.0-c)*0.5 + 200.0*pca*c));
  602.       } else {
  603.     /* Still under table */
  604.     glColor3ub(128/2,  102/2,  179/2);
  605.       }
  606.       
  607.       glPushMatrix();
  608.       glScalef(0.04,  0.0,  0.04);
  609.       glRotatef(0.1 * (-900), 1.0, 0.0, 0.0);
  610.       glRotatef(0.1 * ((int)(10.0*logo_rot[Z])), 0.0, 0.0, 1.0);
  611.       glRotatef(0.1 * ((int)(10.0*logo_rot[Y])), 0.0, 1.0, 0.0);
  612.       glRotatef(0.1 * ((int)(10.0*logo_rot[X])), 1.0, 0.0, 0.0);
  613.       glRotatef(0.1 * (353), 1.0, 0.0, 0.0);
  614.       glRotatef(0.1 * (450), 0.0, 1.0, 0.0);
  615.       draw_logo_shadow();
  616.       glPopMatrix();
  617.     }
  618.     
  619.     if (logo_pos[Y] > 0.0) {
  620.       glPushMatrix();
  621.       if (logo_pos[Y]<0.33) {
  622.     pca /= 4.0;
  623.     c = 1.0 - (logo_pos[Y])/0.33;
  624.     glColor3ub((GLubyte)(255.0*pca*c),
  625.            (GLubyte)(255.0*pca*c),
  626.            (GLubyte)(200.0*pca*c));
  627.       } else {
  628.     glColor3ub(0, 0, 0);
  629.       }
  630.       
  631.       glTranslatef(light_pos[X],  light_pos[Y],  light_pos[Z]);
  632.       glMultMatrixf(&tv[0][0]);
  633.       glTranslatef(-light_pos[X]+logo_pos[X],
  634.            -light_pos[Y]+logo_pos[Y],
  635.            -light_pos[Z]+logo_pos[Z]);
  636.       glScalef(0.04,  0.04,  0.04);
  637.       glRotatef (0.1 * (-900), 1.0, 0.0, 0.0);
  638.       glRotatef (0.1 * ((int)(10.0*logo_rot[Z])), 0.0, 0.0, 1.0);
  639.       glRotatef (0.1 * ((int)(10.0*logo_rot[Y])), 0.0, 1.0, 0.0);
  640.       glRotatef (0.1 * ((int)(10.0*logo_rot[X])), 1.0, 0.0, 0.0);
  641.       glRotatef (0.1 * (353), 1.0, 0.0, 0.0);
  642.       glRotatef (0.1 * (450), 0.0, 1.0, 0.0);
  643.  
  644.  
  645.       glEnable(GL_POLYGON_STIPPLE);
  646.       glPolygonStipple(stipple);
  647.       draw_logo_shadow();
  648.       glDisable(GL_POLYGON_STIPPLE);
  649.       glPopMatrix();
  650.     }
  651.     /*
  652.      * DONE SHADOW 
  653.      */
  654.  
  655.  
  656.     glEnable(GL_DEPTH_TEST);
  657.     glDisable(GL_CULL_FACE);
  658.     glEnable(GL_LIGHTING);
  659.  
  660.     glMatrixMode(GL_PROJECTION);
  661.     glLoadIdentity();
  662.     gluPerspective(.1*(450),  5.0/4.0,  0.5,  20.0);
  663.     glMatrixMode(GL_MODELVIEW);
  664.     glLoadIdentity();
  665.     
  666.     gluLookAt(view_from[X],  view_from[Y],  view_from[Z],
  667.           view_to[X],  view_to[Y],  view_to[Z], 
  668.           0.0, 1.0, 0.0);
  669.     
  670.     glCallList( MAT_HOLDER_RINGS); 
  671.     
  672.     glPushMatrix();
  673.     glTranslatef(light_pos[X],  light_pos[Y],  light_pos[Z]);
  674.     glScalef(0.1,  0.1,  0.1);
  675.     
  676.     x = light_pos[X] - logo_pos[X];
  677.     y = light_pos[Y] - logo_pos[Y];
  678.     z = light_pos[Z] - logo_pos[Z];
  679.     
  680.     if (x!=0.0) {
  681.       a3 = -atan2(z, x)*10.0 RAD;
  682.     } else a3 = 0.0;
  683.     
  684.     a4 = -atan2(sqrt(x*x + z*z), y)*10.0 RAD;
  685.     
  686.     glRotatef (0.1 * ((int)a3), 0.0, 1.0, 0.0);
  687.     glRotatef (0.1 * ((int)a4), 0.0, 0.0, 1.0);
  688.     glRotatef (0.1 * (-900), 1.0, 0.0, 0.0);
  689.     
  690.     glEnable(GL_LIGHT2);
  691.     glEnable(GL_LIGHT3);
  692.     glCallList(MAT_HEMISPHERE);
  693.     glEnable(GL_NORMALIZE);
  694.     draw_hemisphere();
  695.     glDisable(GL_NORMALIZE);
  696.     glPopMatrix();
  697.  
  698.     glDisable(GL_LIGHT2);
  699.     glDisable(GL_LIGHT3); 
  700.     glEnable(GL_LIGHT1);
  701.     glLightfv(GL_LIGHT1, GL_POSITION, light_pos);
  702.     
  703.     if (logo_pos[Y] > -0.33) {
  704.  
  705.       glCallList(MAT_LOGO);
  706.     
  707.       glPushMatrix();
  708.       glTranslatef(logo_pos[X],  logo_pos[Y],  logo_pos[Z]);
  709.       glScalef(0.04,  0.04,  0.04);
  710.       glRotatef (0.1 * (-900), 1.0, 0.0, 0.0);
  711.       glRotatef (0.1 * ((int)(10.0*logo_rot[Z])), 0.0, 0.0, 1.0);
  712.       glRotatef (0.1 * ((int)(10.0*logo_rot[Y])), 0.0, 1.0, 0.0);
  713.       glRotatef (0.1 * ((int)(10.0*logo_rot[X])), 1.0, 0.0, 0.0);
  714.       glRotatef (0.1 * (353), 1.0, 0.0, 0.0);
  715.       glRotatef (0.1 * (450), 0.0, 1.0, 0.0);
  716.       glEnable(GL_LIGHTING);
  717.       draw_logo();
  718.       glPopMatrix();
  719.     }
  720.     
  721.     if (view_from[Y] < 0.0) draw_under_table();
  722.     
  723.     glutSwapBuffers();
  724.  
  725.     if(post_idle) do_post_idle();
  726. }
  727.  
  728. static void do_post_idle(void)
  729. {
  730.   struct timeval current;
  731.   float timediff;    
  732.  
  733.     /* Time jerked -- adjust clock appropriately */
  734.     if (timejerk) {
  735.       timejerk = 0;
  736.       timeoffset = current_time;
  737.       gettimeofday(&start, NULL);
  738.     }
  739.     
  740.     /* Reset our timer */
  741.     if (resetclock) {
  742.       resetclock = 0;
  743.       paused = 0;
  744.       timeoffset = START_TIME;
  745.       gettimeofday(&start, NULL);
  746.     }
  747.     
  748.     /* Compute new time */
  749.     gettimeofday(¤t, NULL);
  750.     timediff = (current.tv_sec - start.tv_sec) + 
  751.       ((double) (current.tv_usec - start.tv_usec)) / 1000000.0;
  752.     if (!paused) {
  753.        current_time = timediff * move_speed + timeoffset;
  754.     }
  755.     
  756.     /* Adjust to new speed */
  757.     if (new_speed != move_speed) {
  758.       move_speed = new_speed;
  759.       timeoffset = current_time;
  760.       gettimeofday(&start, NULL);
  761.     }
  762.     post_idle = 0;
  763. }
  764.  
  765. static void resize_window(int w, int h) 
  766. {
  767.   glMatrixMode(GL_PROJECTION);
  768.   glLoadIdentity();
  769.   gluPerspective (45.0, 5.0/4.0, 0.5, 20.0); 
  770.   glMatrixMode(GL_MODELVIEW);
  771.   glLoadIdentity();
  772.   glViewport(0, 0, w, h);
  773. }
  774.  
  775. static void initialize(void)
  776. {
  777.     int attr;
  778.  
  779.     attr = doublebuffer ? RGBA_DB_attributes : RGBA_SB_attributes;
  780.     glutInitDisplayMode(attr);
  781.     glutInitWindowSize(300, 240);
  782.     glutCreateWindow("Ideas");
  783.  
  784.     if (multisample) glEnable(GL_POLYGON_SMOOTH); 
  785.     
  786.     init_lights();
  787.     init_materials();
  788.  
  789.     build_table();
  790.  
  791.     view_from_spline = calc_spline_params(view_from_ctl, TIME);
  792.     view_to_spline = calc_spline_params(view_to_ctl, TIME);
  793.     light_pos_spline = calc_spline_params(light_pos_ctl, TIME);
  794.     logo_pos_spline = calc_spline_params(logo_pos_ctl, TIME);
  795.     logo_rot_spline = calc_spline_params(logo_rot_ctl, TIME);
  796.  
  797.     glutReshapeFunc(resize_window);
  798.     glutDisplayFunc(display);
  799.     glutMouseFunc(mouse);
  800.     glutKeyboardFunc(keyboard);
  801.     glutVisibilityFunc(vis);
  802.  
  803.     glMatrixMode(GL_MODELVIEW);
  804. }
  805.  
  806.  
  807. static void build_table(void) 
  808. {
  809.     float i, j;
  810.  
  811.     for (j=0.0; j<=TABLERES*1.0; j+=1.0) {
  812.     for (i=0.0; i<=TABLERES*1.0; i+=1.0) {
  813.         table_points[(int)j][(int)i][Z] = (i-TABLERES*1.0/2.0)/2.0;
  814.         table_points[(int)j][(int)i][X] = (j-TABLERES*1.0/2.0)/2.0;
  815.         table_points[(int)j][(int)i][Y] = 0.0;
  816.     }
  817.     }
  818. }
  819.  
  820.  
  821. void draw_table(void)
  822. {
  823.     float c;
  824.     int i, j;
  825.     int k, l;
  826.     float ov[3], lv[3];
  827.  
  828.     glDisable(GL_DEPTH_TEST);
  829.     glDisable(GL_LIGHTING);
  830.  
  831.     ov[X] = light_pos[X]-logo_pos[X];
  832.     ov[Y] = light_pos[Y]-logo_pos[Y];
  833.     ov[Z] = light_pos[Z]-logo_pos[Z];
  834.  
  835.     normalize(ov);
  836.  
  837.     for (j=0; j<=TABLERES; j++) {
  838.       for (i=0; i<=TABLERES; i++) {
  839.     lv[X] = light_pos[X] - table_points[j][i][X];
  840.     lv[Y] = light_pos[Y] - table_points[j][i][Y];
  841.     lv[Z] = light_pos[Z] - table_points[j][i][Z];
  842.     normalize(lv);
  843.     if ((c = dot(lv, ov))<0.0) c = 0.0;
  844.     c = c * c * c * lv[Y] * 255.0;
  845.     /* fade */
  846.     if ((current_time>TIME-5.0) && (current_time<TIME-3.0)) 
  847.       c *= 1.0 - (current_time-(TIME-5.0)) * 0.5;
  848.     
  849.     tablecolors[j][i] = (int)c;
  850.       }
  851.     }
  852.     
  853.     
  854.     for (l=0; l<TABLERES; l++) {
  855.       
  856.       glBegin(GL_TRIANGLE_STRIP);
  857.       for (k=0; k<=TABLERES; k++) {
  858.     glColor3ub(tablecolors[l][k],
  859.            tablecolors[l][k],
  860.            tablecolors[l][k]);
  861.     glVertex3fv(table_points[l][k]);
  862.  
  863.     glColor3ub(tablecolors[l+1][k],
  864.            tablecolors[l+1][k], 
  865.            tablecolors[l+1][k]);
  866.     glVertex3fv(table_points[l+1][k]);
  867.     
  868.       }
  869.     glEnd();
  870.     }
  871.  
  872.     if (logo_pos[Y]>-0.33 && logo_pos[Y]<0.33) {
  873.     glEnable(GL_DEPTH_TEST);
  874.     }
  875.  
  876.     pca = 0.0;
  877.     glBegin(GL_POLYGON);
  878.     for (i=0; i<4; i++) {
  879.       lv[X] = light_pos[X] - paper_points[i][X];
  880.       lv[Y] = light_pos[Y] - paper_points[i][Y];
  881.       lv[Z] = light_pos[Z] - paper_points[i][Z];
  882.       normalize(lv);
  883.       if ((c = dot(lv, ov))<0.0) c = 0.0;
  884.       c = c * c * c * lv[Y];
  885.       /* fade */
  886.       if ((current_time>TIME-5.0) && (current_time<TIME-3.0)) 
  887.     c *= 1.0 - (current_time-(TIME-5.0)) * 0.5;
  888.       
  889.       pcr = c * 255; pcg = c * 255; pcb = c * 200;
  890.       pca += c;
  891.       glColor3ub((GLubyte)pcr,  (GLubyte)pcg,  (GLubyte)pcb);
  892.       glVertex3fv(paper_points[i]);
  893.     }
  894.     glEnd();
  895.  
  896.     glPushMatrix();
  897.     glRotatef (0.1 * (-184), 0.0, 1.0, 0.0);
  898.     glTranslatef(-0.3, 0.0, -0.8);
  899.     glRotatef (0.1 * (-900), 1.0, 0.0, 0.0);
  900.     glScalef(0.015, 0.015, 0.015);
  901.  
  902.  
  903.     if (current_time>TIME*1.0-5.0) {
  904.     c = (current_time-(TIME*1.0-5.0))/2.0;
  905.     glColor3ub((GLubyte)(c*255.0),  (GLubyte)(c*255.0),  (GLubyte)(c*255.0));
  906.     } else glColor3ub(0,  0,  0);
  907.  
  908.     glDisable(GL_DEPTH_TEST);
  909.  
  910.     draw_i();
  911.     glTranslatef(3.0,  0.0,  0.0);
  912.  
  913.     draw_d();
  914.     glTranslatef(6.0,  0.0,  0.0);
  915.  
  916.     draw_e();
  917.     glTranslatef(5.0,  0.0,  0.0);
  918.  
  919.     draw_a();
  920.     glTranslatef(6.0,  0.0,  0.0);
  921.  
  922.     draw_s();
  923.     glTranslatef(10.0,  0.0,  0.0);
  924.  
  925.     draw_i();
  926.     glTranslatef(3.0,  0.0,  0.0);
  927.  
  928.     draw_n();
  929.     glTranslatef(-31.0,  -13.0,  0.0);
  930.  
  931.     draw_m();
  932.     glTranslatef(10.0,  0.0,  0.0);
  933.  
  934.     draw_o();
  935.     glTranslatef(5.0,  0.0,  0.0);
  936.  
  937.     draw_t();
  938.     glTranslatef(4.0,  0.0,  0.0);
  939.  
  940.     draw_i();
  941.     glTranslatef(3.5,  0.0,  0.0);
  942.  
  943.     draw_o();
  944.     glTranslatef(5.0,  0.0,  0.0);
  945.  
  946.     draw_n();
  947.  
  948.     glPopMatrix();
  949.  
  950. }
  951.  
  952.  
  953.  
  954. void draw_under_table(void) 
  955. {
  956.     int k, l;
  957.  
  958.     glDisable(GL_DEPTH_TEST);
  959.  
  960.  
  961.     glColor3ub(0,  0,  0);
  962.  
  963.     for (l=0; l<TABLERES; l++) {
  964.  
  965.     glBegin(GL_TRIANGLE_STRIP);
  966.     for (k=0; k<=TABLERES; k++) {
  967.  
  968.         glVertex3fv(table_points[l][k]);
  969.         glVertex3fv(table_points[l+1][k]);
  970.  
  971.     }
  972.     glEnd();
  973.     }
  974.  
  975.     glEnable(GL_DEPTH_TEST); 
  976.  
  977. }
  978.  
  979. static void calc_spline(vector v, parameter *params, float current_time)
  980. {
  981.  
  982.     float t;
  983.     int ti, i;
  984.  
  985.     t = current_time - (float)((int)current_time);
  986.  
  987.     ti = current_time;
  988.     /* XXX Hack so that time will not overflow the params array.
  989.        The size of the spline params array should not be built into
  990.        this routine this way. */
  991.     if (ti >= (TIME - 3)) {
  992.       ti = TIME - 4;
  993.     }
  994.  
  995.     for (i=0; i<3; i++) {
  996.     v[i] = params[ti][3][i] +
  997.            params[ti][2][i] * t +
  998.            params[ti][1][i] * t * t +
  999.            params[ti][0][i] * t * t * t;
  1000.     }
  1001.  
  1002. }
  1003.  
  1004. static parameter *calc_spline_params(vector *ctl_pts, int n)
  1005. {
  1006.  
  1007.     int i, j;
  1008.     parameter *params;
  1009.  
  1010.     if (n<4) {
  1011.     fprintf(stderr,
  1012.         "calc_spline_params: not enough control points\n");
  1013.     return (NULL);
  1014.     }
  1015.  
  1016.     params = (parameter *)malloc(sizeof(parameter) * (n-3));
  1017.  
  1018.     for (i=0; i<n-3; i++) {
  1019.  
  1020.     for (j=0; j<3; j++) {
  1021.  
  1022.         params[i][3][j] = ctl_pts[i+1][j];
  1023.         params[i][2][j] = ctl_pts[i+2][j] - ctl_pts[i][j];
  1024.         params[i][1][j] =  2.0 * ctl_pts[i][j] +
  1025.                   -2.0 * ctl_pts[i+1][j] +
  1026.                    1.0 * ctl_pts[i+2][j] +
  1027.                   -1.0 * ctl_pts[i+3][j];
  1028.         params[i][0][j] = -1.0 * ctl_pts[i][j] +
  1029.                    1.0 * ctl_pts[i+1][j] +
  1030.                   -1.0 * ctl_pts[i+2][j] +
  1031.                    1.0 * ctl_pts[i+3][j];
  1032.  
  1033.     }
  1034.     }
  1035.  
  1036.     return (params);
  1037. }
  1038.  
  1039.  
  1040. static void normalize(vector v)
  1041. {
  1042.     float r;
  1043.  
  1044.     r = sqrt(v[X]*v[X] + v[Y]*v[Y] + v[Z]*v[Z]);
  1045.  
  1046.     v[X] /= r;
  1047.     v[Y] /= r;
  1048.     v[Z] /= r;
  1049. }
  1050.  
  1051.  
  1052. static float dot(vector v1, vector v2)
  1053. {
  1054.     return v1[X]*v2[X]+v1[Y]*v2[Y]+v1[Z]*v2[Z];
  1055. }
  1056.  
  1057.